import { View, Text } from "@tarojs/components";
import { useLoad } from "@tarojs/taro";
import "./index.scss";
import React, { useState, useEffect } from "react";
import { Solar, SolarMonth, HolidayUtil } from "lunar-typescript";

const now = Solar.fromDate(new Date());
const holidayArr = [
  {
    name: "元旦",
    date: "2023-12-30",
  },
  {
    name: "春节",
    date: "2024-02-10",
  },
  {
    name: "清明节",
    date: "2024-04-04",
  },
  {
    name: "劳动节",
    date: "2024-05-01",
  },
  ,
  {
    name: "端午节",
    date: "2024-06-08",
  },
  {
    name: "中秋节",
    date: "2024-09-015",
  },
  ,
  {
    name: "国庆节",
    date: "2024-10-01",
  },
];

const findNearestHoliday = () => {
  const today: any = new Date();
  let nearestHoliday: any = null;
  let minDifference = Infinity;

  holidayArr.forEach((holiday: any) => {
    const holidayDate: any = new Date(holiday.date);
    const difference = (holidayDate - today) / (1000 * 60 * 60 * 24);

    if (difference >= 0 && difference < minDifference) {
      nearestHoliday = holiday;
      minDifference = difference;
    }
  });

  return nearestHoliday
    ? { ...nearestHoliday, daysUntil: Math.ceil(minDifference) }
    : null;
};
interface Day {
  day: number | undefined;
  text?: string;
  isFestival?: boolean;
  isRest?: boolean;
  isToday?: boolean;
  isHoliday?: boolean;
  isOther?: boolean;
}

interface Week {
  index?: Number;
  days?: Array<Day>;
}

export default function Calendar() {
  useLoad(() => {
    console.log("加载");
  });
  const [state, setState] = useState({
    year: now.getYear(),
    month: now.getMonth(),
    weekStart: 1,
    heads: ["一", "二", "三", "四", "五", "六", "日"],
    weeks: [] as Week[],
    chooseItem: 0,
    nMonth: "",
    nDay: "",
    xingZuo: "",
  });
  /**
   * 数据变化后触发
   */
  useEffect(() => {
    render();
    updateNong(state.year, state.month, state.chooseItem);
  }, [state.year, state.month]);

  useEffect(() => {
    updateNong(state.year, state.month, state.chooseItem);
  }, [state.chooseItem]);
  /**
   * 计算出月份日期
   * @param d
   * @returns
   */
  const buildDay = (d: Solar) => {
    const lunar = d.getLunar();
    const day: Day = {
      day: d.getDay(),
    };
    let text = lunar.getDayInChinese();
    if (1 === lunar.getDay()) {
      text = lunar.getMonthInChinese() + "月";
    }
    let otherFestivals = d.getOtherFestivals();
    otherFestivals = lunar.getOtherFestivals();

    if (otherFestivals.length > 0) {
      text = otherFestivals[0];
      day.isFestival = true;
    }
    let festivals = d.getFestivals();

    if (festivals.length > 0) {
      text = festivals[0];
      day.isFestival = true;
    }
    festivals = lunar.getFestivals();

    if (festivals.length > 0) {
      text = festivals[0];
      day.isFestival = true;
    }
    const jq = lunar.getJieQi();
    if (jq) {
      text = jq;
      day.isFestival = true;
    }
    day.text = text;
    if (d.toYmd() === now.toYmd()) {
      day.isToday = true;
    }
    if (d.getMonth() !== state.month) {
      day.isOther = true;
    }
    const h = HolidayUtil.getHoliday(d.getYear(), d.getMonth(), d.getDay());
    if (h) {
      day.isHoliday = true;
      day.isRest = !h.isWork();
    }
    return day;
  };
  /**
   * 更新农历信息
   * @param year
   * @param month
   * @param day
   */
  const updateNong = (year: number, month: number, day: number) => {
    const solar = Solar.fromYmd(year, month, day || now.getDay());
    const lunar = solar.getLunar();
    setState((prevState) => ({
      ...prevState,
      nMonth: lunar.getMonthInChinese(),
      nDay: lunar.getDayInChinese(),
      xingZuo: solar.getXingZuo(),
    }));
  };
  /**
   * 获取当前月
   */
  const render = () => {
    const month = SolarMonth.fromYm(state.year, state.month);
    const weeks: Week[] = [];
    month.getWeeks(state.weekStart).forEach((w) => {
      const week: Week = {};
      week.index = w.getIndexInYear();
      const days: Day[] = [];
      w.getDays().forEach((d) => {
        days.push(buildDay(d));
      });
      week.days = days;
      weeks.push(week);
    });

    for (let item of weeks[0].days || []) {
      if (item.day != 1) {
        item.day = undefined;
        item.text = "";
        item.isHoliday = false;
        item.isRest = false;
      } else if (item.day == 1) {
        break;
      }
    }
    const index = (weeks[weeks.length - 1].days || []).findIndex(
      (item: Day) => item.day == 1
    );
    if (index != -1) {
      weeks[weeks.length - 1].days = weeks[weeks.length - 1].days?.slice(
        0,
        index
      );
    }

    setState((prevState) => ({
      ...prevState,
      weeks,
    }));
  };
  /**
   * 前一个月
   */
  const onPrevMonth = () => {
    const month = SolarMonth.fromYm(state.year, state.month)!.next(-1)!;
    setState((prevState) => ({
      ...prevState,
      year: month.getYear(),
      month: month.getMonth(),
      chooseItem: 1,
    }));
  };
  /**
   * 下一个月
   */
  const onNextMonth = () => {
    const month = SolarMonth.fromYm(state.year, state.month)!.next(1)!;
    setState((prevState) => ({
      ...prevState,
      year: month.getYear(),
      month: month.getMonth(),
      chooseItem: 1,
    }));
  };
  /**
   * 回到今天
   */
  const onToday = () => {
    setState((prevState) => ({
      ...prevState,
      year: now.getYear(),
      month: now.getMonth(),
      chooseItem: 0,
    }));
  };
  /**
   * 切换日期选择
   * @param day
   */
  const handleChoose = (day: Day) => {
    setState((prevState) => ({
      ...prevState,
      chooseItem: day.day || prevState.chooseItem,
    }));
  };
  const { name, daysUntil } = findNearestHoliday();
  const pa = {
    paddingTop: state.weeks.length === 5 ? "14px" : "4px",
  };
  return (
    <View>
      <View className="content">
        <View className="top-date">
          <View className="date">
            {state.year}年 {state.month}月
          </View>
          <View className="select">
            <View className="icon" onClick={onPrevMonth}>
              &lt;
            </View>
            <View className="today" onClick={onToday}>
              今天
            </View>
            <View className="icon" onClick={onNextMonth}>
              &gt;
            </View>
          </View>
        </View>
        <View className="header">
          {state.heads.map((item) => (
            <View className="header-item" key={item}>
              {item}
            </View>
          ))}
        </View>
        <View>
          {state.weeks.map((week: any, index) => (
            <View key={index} className="row" style={pa}>
              {week.days.map((day: any, dayIndex: number) => (
                <View
                  key={dayIndex}
                  className={`${"row-item"} ${
                    state.chooseItem === day.day && !day.isToday ? "choose" : ""
                  }`}
                  onClick={() => handleChoose(day)}
                >
                  <Text className="date-text">{day.day ? day.day : ""}</Text>
                  <Text
                    className={`${day.isHoliday ? "holiday" : "text"} ${
                      day.isToday
                        ? state.chooseItem === day.day || !state.chooseItem
                          ? "item-today"
                          : "item-not"
                        : state.chooseItem === day.day
                        ? "color1"
                        : "color2"
                    }`}
                  >
                    {day.text.slice(0, 4)}
                  </Text>
                  {day.isHoliday && (
                    <Text>
                      {" "}
                      {day.isRest ? (
                        <Text className="xiu">休</Text>
                      ) : (
                        <Text className="ban">班</Text>
                      )}
                    </Text>
                  )}
                </View>
              ))}
            </View>
          ))}
        </View>
      </View>
      <View className="nong">
        农历{" "}
        <Text className="font">
          {state.nMonth}月{state.nDay}
        </Text>{" "}
        {state.xingZuo}座
      </View>
      <View className="last">
        距{name} 还有<Text className="last-day">{daysUntil}</Text>天
        <View>放假啦～</View>
      </View>
    </View>
  );
}
